//
//  WmcAlbumManager.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/23.
//

import Kingfisher
import Photos
import UIKit
import YPBedrock

extension WmcAlbumManager {
    class AlbumModel: NSObject {
        // Lifecycle

        init(with collection: PHAssetCollection, result: PHFetchResult<PHAsset>) {
            self.collection = collection
            self.result = result
            self.name = collection.localizedTitle ?? ""
            self.count = result.count
        }

        // Internal

        var collection: PHAssetCollection
        var result: PHFetchResult<PHAsset>
        var name: String
        var count: Int

        /// 选中状态
        var isSelected: Bool = false

        override var description: String {
            return "\(name)-[\(count)]"
        }

        override var hash: Int {
            return collection.hash
        }
    }
}

// MARK: - [WmcAlbumManager]

class WmcAlbumManager {
    // Public

    /// 单例实例化
    public static let shared: WmcAlbumManager = {
        let manager = WmcAlbumManager()
        return manager
    }()

    // Internal

    static var defaultAlbumName = "鱼泡水印相机"

    static func getAllAlbum() -> [AlbumModel] {
        var albums: [AlbumModel] = []
        // 配置
        let option: PHFetchOptions = .init()
        option.predicate = NSPredicate(format: "mediaType == %ld", PHAssetMediaType.image.rawValue)
        option.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
        // 获取相册
        let myPhotoStreamAlbum: PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumMyPhotoStream, options: nil)
        let smartAlbums: PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
        let syncedAlbums: PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumSyncedAlbum, options: nil)
        let sharedAlbums: PHFetchResult = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .albumCloudShared, options: nil)
        var albumList: [PHFetchResult<PHAssetCollection>] = [myPhotoStreamAlbum, smartAlbums, syncedAlbums, sharedAlbums]
        if let topLevelUserCollections: PHFetchResult = PHAssetCollection.fetchTopLevelUserCollections(with: nil) as? PHFetchResult<PHAssetCollection> {
            albumList.append(topLevelUserCollections)
        }
        
        // 遍历所有相册
        for fetchResult in albumList {
            fetchResult.enumerateObjects { collection, _, _ in
                if NSStringFromClass(type(of: collection)) == "PHAssetCollection" {
                    let result: PHFetchResult = PHAsset.fetchAssets(in: collection, options: option)
                    // 条件池
                    var conditions: [Bool] = [
                        (collection.estimatedAssetCount <= 0), // 空相册
                        result.count <= 0, // 无照片相册
                        (collection.assetCollectionSubtype == .smartAlbumAllHidden), // 隐藏相册
                        (collection.assetCollectionSubtype.rawValue == 1000000201), // 『最近删除』相册
                        (collection.assetCollectionSubtype == .smartAlbumPanoramas), // 全景照片
                        (collection.assetCollectionSubtype == .smartAlbumVideos), // 视频
                        (collection.assetCollectionSubtype == .smartAlbumSlomoVideos), // 慢动作视频
                    ]
                    if #available(iOS 10.3, *) {
                        conditions.append((collection.assetCollectionSubtype == .smartAlbumLivePhotos) // 实况
                        )
                    }
                    // 条件池必须全部不满足
                    if !conditions.contains(true) {
                        if isCameraRollAlbum(metadata: collection) {
                            albums.insert(.init(with: collection, result: result), at: 0)
                        } else {
                            albums.append(.init(with: collection, result: result))
                        }
                    }
                }
            }
        }
        return albums
    }

    /// 获取Asset图片
    /// 如果图片大小过大时，建议关闭内存缓存
    static func asyncLoadImage(asset: PHAsset,
                               photoSize: CGSize = 100.yp.cgSize,
                               squareCenterMode: Bool = true,
                               imageBlock: @escaping YPBlock.OneParam<UIImage>)
    {
        YPGCD.Async { // 转异步获取
            // 准备获取
            loadImage(for: asset, targetSize: photoSize) { img in
                var resultImage: UIImage?
                if squareCenterMode {
                    if let img = img.yp.set(squareMode:.center) {
                        resultImage = img
                    }
                } else {
                    resultImage = img
                }
                if let resultImage = resultImage {
                    YPGCD.Main {
                        imageBlock(resultImage)
                    }
                }
            }
        }
    }

    static func loadImage(for asset: PHAsset,
                          targetSize: CGSize,
                          contentMode: PHImageContentMode = .aspectFill,
                          imageBlock: @escaping YPBlock.OneParam<UIImage>)
    {
        let options = PHImageRequestOptions()
        options.resizeMode = .fast
        options.isSynchronous = true
        PHImageManager.default().requestImage(for: asset,
                                              targetSize: targetSize,
                                              contentMode: contentMode,
                                              options: options) { img, _ in
            if let img = img {
                imageBlock(img)
            }
        }
    }

    static func isCameraRollAlbum(metadata: PHAssetCollection) -> Bool {
        var versionStr: String = UIDevice.current.systemVersion.replacingOccurrences(of: ".", with: "")
        if versionStr.count < 1 {
            versionStr.append("00")
        } else if versionStr.count <= 2 {
            versionStr.append("0")
        }
        let versionNum = versionStr.yp.float
        if versionNum >= 800, versionNum <= 802 {
            return metadata.assetCollectionSubtype == .smartAlbumRecentlyAdded
        } else {
            return metadata.assetCollectionSubtype == .smartAlbumUserLibrary
        }
    }

    /// 直接存入自己默认相册
    static func saveMyAlbumCollection(videoUrl: URL, completeBlock: YPBlock.Empty? = nil) {
        let photoAlbumStatus = WmcAuthorizedManager.photoAlbum()
        if photoAlbumStatus.info.isAvailable {
            // 存入系统相册
            getAlbumCollection() { assetCollection in
                if let assetCollection = assetCollection {
                    saveVideo(url: videoUrl, assetCollection: assetCollection, completeBlock: completeBlock)
                }
            }
        }
//        else {
//            WmcAuthorizedManager.handleAlbumAuthorizationNotAvailable()
//        }
    }

    /// 直接存入自己默认相册
    static func saveMyAlbumCollection(image: UIImage, completeBlock: YPBlock.Empty? = nil) {
        let photoAlbumStatus = WmcAuthorizedManager.photoAlbum()
        if photoAlbumStatus.info.isAvailable {
            // 存入系统相册
            getAlbumCollection() { assetCollection in
                if let assetCollection = assetCollection {
                    saveImage(image: image, assetCollection: assetCollection, completeBlock: completeBlock)
                }
            }
        }
//        else {
//            WmcAuthorizedManager.handleAlbumAuthorizationNotAvailable()
//        }
    }

    /// 获取相册，不传相册名默认找自己的默认相册
    static func getAlbumCollection(name: String = defaultAlbumName,
                                   completion: @escaping (PHAssetCollection?) -> Void)
    {
        var localIdentifier = Self.getAlbumIdentifier()

        // 按identifiers查询相册
        let queryAlbumCollection: ([String]) -> [PHAssetCollection] = { identifiers in
            let fetchResult = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: identifiers, options: nil)

            var list: [PHAssetCollection] = []
            fetchResult.enumerateObjects { assetCollection, index, stop in
                list.append(assetCollection)
            }

            return list
        }

        // 按名称查询相册
        let queryCommonNameAlbumCollection: () -> PHAssetCollection? = {
            let list: [AlbumModel] = WmcAlbumManager.getAllAlbum()
            var wmcAssetCollection: PHAssetCollection?

            // 遍历鱼泡水印相机相册
            for (_, item) in list.enumerated() {
                if item.name == name {
                    wmcAssetCollection = item.collection
                    break
                }
            }

            return wmcAssetCollection
        }

        // 创建相册
        let creatAlbumCollection: () -> Void = {
            PHPhotoLibrary.shared().performChanges {
                localIdentifier = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: name).placeholderForCreatedAssetCollection.localIdentifier
            } completionHandler: { isSuccess, error in
                if isSuccess {
                    Self.setAlbumIdentifier(identifier: localIdentifier)
                    let assetCollection = queryAlbumCollection([localIdentifier]).first
                    completion(assetCollection)
                }
            }
        }

        if localIdentifier.isEmpty {
            // 如果identifiers为空，优先查找同名相册，如果没有查找到则创建相册
            if let wmcAssetCollection = queryCommonNameAlbumCollection() {
                setAlbumIdentifier(identifier: wmcAssetCollection.localIdentifier)
                completion(wmcAssetCollection)
            } else {
                creatAlbumCollection()
            }
        } else {
            // 按identifiers查询相册，如果没有查找到则创建相册
            if let assetCollection = queryAlbumCollection([localIdentifier]).first {
                completion(assetCollection)
            } else {
                creatAlbumCollection()
            }
        }
    }

    /// 保存图片到某个相册
    static func saveImage(image: UIImage, assetCollection: PHAssetCollection, completeBlock: YPBlock.Empty? = nil) {
        PHPhotoLibrary.shared().performChanges {
            let assetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
            let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset
            let albumChangeRequest = PHAssetCollectionChangeRequest(for: assetCollection)
            albumChangeRequest?.addAssets([assetPlaceholder] as NSFastEnumeration)
        } completionHandler: { isSuccess, error in
            YPGCD.Main {
                completeBlock?()
            }
        }
    }

    /// 保存视频到某个相册
    static func saveVideo(url: URL, assetCollection: PHAssetCollection, completeBlock: YPBlock.Empty? = nil) {
        PHPhotoLibrary.shared().performChanges {
            guard let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url) else { return }
            let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset
            let albumChangeRequest = PHAssetCollectionChangeRequest(for: assetCollection)
            albumChangeRequest?.addAssets([assetPlaceholder] as NSFastEnumeration)
        } completionHandler: { isSuccess, error in
            YPGCD.Main {
                completeBlock?()
            }
        }
    }

    // Private

    private static func getAlbumIdentifier() -> String {
        return UserDefaults.standard.string(forKey: "com.watermark.albumIdentidier") ?? ""
    }

    private static func setAlbumIdentifier(identifier: String) {
        UserDefaults.standard.set(identifier, forKey: "com.watermark.albumIdentidier")
        UserDefaults.standard.synchronize()
    }
}
